// $Id: jquery.doubleClickAds.js 4 2009-11-20 05:35:10Z christopher.jf.hopper $
/**
 * @file
 * jQuery Plug-in for DoubleClick Advertisements. 
 * 
 * Inserts DoubleClick Advertisements into the page.
 *
 * @access public
 * @version $Rev: 4 $ 
 * @author Christopher Hopper <christopher.jf.hopper@gmail.com>
 * 
 */

(function($) {

  // Static DoubleClick properties and methods. 
  $.doubleClickAds = {
    // Configure the DoubleClick ads for a site. 
    config : function (name, value) {
      var options = name;
      
      // Deal with individual settings values. 
      if ( name.constructor == String) {
        options = { };
        options[name] = value;
      }
      
      // option is an object with name value pairs. 
      for (name in options) {
        // If the property exists and we have a value, then set it. 
        if (this[name] && options[name]) this[name] = options[name];
      }
      
      // Allow chaining. 
      return this;
    },
    
    // Hostname of the DoubleClick ad serving web server. 
    hostname : 'ad.doubleclick.net',

    // The domain requesting the advertisement. 
    domain : (function () {
      var re = new RegExp('.*?([a-z0-9][a-z0-9\-]{1,63}\.[a-z\.]{2,6})$');
      return window.location.hostname.replace(re, '$1');
    })(), 

    // The zone of the requested advertisement. 
    zone : (function () {
      var zone = window.location.path || 'home',
        ids = zone.indexOf('/'), idd = zone.indexOf('.');
      
      return (ids > 0) && zone.substr(0, ids) ||
        (idd > 0) && zone.substr(0, idd) || 
        zone;
    })(),

    // Return the href for the DoubleClick advertisement.
    href : function (d) { 
      if (!d) d = { };
      return window.location.protocol + '//' + this.hostname + '/adj/' 
        + this.domain + '/' + this.zone + ';' + this.dataString(d);
    },
    
    // A number, incremented for each ad, used in every href.
    _tile : 0, 
    
    // Increment and get the value of tile used in every href.
    tile : function () { return ++this._tile; },
    
    // Get data pairs as a string for use in href. 
    dataString : function (d) {
      // Define variables for this scope. 
      var pairs = new Array(), 
        adData = { };
      
      this.data.ord = this.ord();
      
      this.data.tile = this.tile();

      if (d) {
        $.extend(adData, this.data, d);
      }
      else {
        adData = this.data;
      }
      
      // Concatenate the data pairs for use in the DoubleClick URI. 
      $.each(adData, function (key, val) {
        // If this is a property and has a value, use it. 
        var pair = encodeURIComponent(key) + "="
          + encodeURIComponent(val);
        
        pairs.push(pair);
      });
      
      return pairs.join(';') + ';';
    },
    
    // Unique number used in every href. 
    _ord : 0,
    
    // Get the value of ord used in every href. 
    ord : function () {
      if (!this._ord) {
        var r = 0, d = new Date();
        
        while (r == 0) r = Math.floor(Math.random() * 1000);
        
        this._ord = d.getTime().toString() + r.toString();
      }
      
      return this._ord;
    }, 
    
    data : {  },
    
    waitForIframe : function (iframeId, count) {
      var iframe = document.getElementById(iframeId);
      var actualHeight = iframe.contentWindow.document.height 
        || iframe.contentWindow.window.document.body && iframe.contentWindow.window.document.body.scrollHeight
        || -1;
      if (iframe.height != actualHeight || count++ < 1000) {
        if (actualHeight > 0) iframe.height = actualHeight;
        setTimeout("$.doubleClickAds.waitForIframe('"+iframeId+"', "+ count +");", 250);
      }
    }
  };

  // jQuery appendDoubleClickAd method. 
  $.fn.appendDoubleClickAd = function(data, settings) {
    // Default attributes for <IFRAME/> Ad container
    var iframeAttr = { 'frameBorder': 0, 'scrolling': "no", 'vspace': 0
      , 'marginWidth': 0, 'marginHeight': 0, 'hspace': 0
      , 'allowTransparency': true, 'width': (settings.width ? 
      settings.width : "100%"), 'height': (settings.height ? 
      settings.height : "1") },
      // default configuration options. 
      config = { 'iframeCSS' : false }; 

    // Extend the default configuration with any given settings. 
    if (settings) $.extend(config, settings);
    
    this.each(function() {
      var uri = $.doubleClickAds.href(data);

      // Set the IFRAME "id" and "name" for each advertisement. 
      iframeAttr.id = iframeAttr.name = "doubleclick-ads-iframe-"+ $.doubleClickAds._tile;
      
      // Create the IFRAME element. 
      $('<IFRAME/>')
        .attr(iframeAttr)
        // Append the IFRAME to the document. 
        .appendTo(this)
        // Write the DoubleClick Advertisement into the IFRAME. 
        .each(function () {
          // Get a pointer to the IFRAME document object and DOM. 
          var doc = this.contentWindow.document || 
            this.contentWindow.window.document || 
            this.contentDocument;
          
          // Open the IFRAME document. 
          if (!$.browser.msie && doc.open) doc.open();
          
          // Ensure anchors do not open in the IFRAME by default. 
          doc.write('<BASE target="_top" />');
          
          // If a specific advert CSS file is defined, use it. 
          if (settings.iframeCSS) 
            doc.write('<STYLE type="text/css" media="all">@import "'+ settings.iframeCSS +'";</STYLE>');
          
          // Add the advertisement from DoubleClick. 
          doc.write('<SCR'+'IPT type="text/javascript" src="'+ uri +'"></SCR'+'IPT>');
          
          // Close the IFRAME document. 
          if (!$.browser.msie && doc.close) doc.close();
        })
        // Resize the IFRAME after it has loaded. 
        .load(function () {
          if (!settings.height) this.height = this.contentWindow.document.height 
            || this.contentWindow.window.document.body && this.contentWindow.window.document.body.scrollHeight;
        });
        
        // If MSIE, Resize the IFRAME using a looping setTimeout call.
        if ($.browser.msie && !settings.height) $.doubleClickAds.waitForIframe(iframeAttr.id, 1);
    });

    // Support jQuery chaining.
    return this;
  };
})(jQuery);
